package no.hig.imt4721.util;

import java.util.ArrayList;
import java.util.List;

import no.hig.imt4721.model.Repetition;
import no.hig.imt4721.model.Session;
import no.hig.imt4721.model.Subject;

public class Statistics
{
	public static double calculateMean(List<Double> values)
	{
		double sum = 0;
		
		for(int i = 0; i < values.size(); i++)
		{
			sum += values.get(i);
		}
		
		return sum / values.size();
	}
	
	public static double calculateMean(Double[] values)
	{
		double sum = 0;
		
		for(int i = 0; i < values.length; i++)
		{
			sum += values[i];
		}
		
		return sum / values.length;
	}
	
	public static double calculateStandardDeviation(List<Double> values)
	{
		double sum = 0;
		double mean = calculateMean(values);
		
		for(int i = 0; i < values.size(); i++)
		{
			sum += Math.pow(values.get(i) - mean, 2);
		}
		
		return Math.sqrt(sum / values.size());
	}
	
	public static double calculateStandardDeviation(Double[] values)
	{
		double sum = 0;
		double mean = calculateMean(values);
		
		for(int i = 0; i < values.length; i++)
		{
			sum += Math.pow(values[i] - mean, 2);
		}
		
		return Math.sqrt(sum / values.length);
	}
	
	
	
	public static double calculateAverageAbsoluteDeviation(Double[] values)
	{
		double sum = 0;
		double mean = calculateMean(values);
		
		for(int i = 0; i < values.length; i++)
		{
			sum += Math.abs(values[i] - mean);
		}
		
		return (sum / values.length);
	}
	
	
	public static double calculateAverageAbsoluteDeviation(List<Double> values)
	{
		double sum = 0;
		double mean = calculateMean(values);
		
		for(int i = 0; i < values.size(); i++)
		{
			sum += Math.abs(values.get(i) - mean);
		}
		
		return (sum / values.size());
	}
	
	public static double calculateMedian(List<Double> values)
	{
		if(values.size() % 2 == 0) // Even amount of values
		{
			double middleValue1 = values.get(values.size() / 2);
			double middleValue2 = values.get((values.size() / 2) + 1);
			
			return (middleValue1 + middleValue2) / 2;
		}
		else // Odd amount of values
			return values.get(values.size() / 2);
	}
	
	
	public static List<Double> calculateLearningCurve(List<Subject> subjects)
	{
		List<Double> result = new ArrayList<Double>();
		
		for(int sessionNr = 0; sessionNr < 8; sessionNr++)
		{
			double sumOfAverageSDValues = 0;
			
			for(Subject subject : subjects)
			{
				Session session = subject.getSessions().get(sessionNr);
				
				double sumOfSDValues = 0;
				
				for(int i = 0; i < session.getRepetitions().get(0).getLengthOfRow() ; i++)
				{
					List<Double> values = new ArrayList<Double>();
					
					for(Repetition repetition : session.getRepetitions())
					{
						values.add(repetition.getRowElement(i));
					}
					
					sumOfSDValues += Statistics.calculateStandardDeviation(values);
				}
				
				sumOfAverageSDValues += sumOfSDValues / session.getRepetitions().get(0).getLengthOfRow();
			}
			
			double averageofaverageSDValues = sumOfAverageSDValues / subjects.size();
			
			result.add(averageofaverageSDValues);
		}
		
		return result;
	}
}
